﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using MemoryPack;
#if UNITY_EDITOR
using Sirenix.OdinInspector;
#endif

namespace Hsenl {
    /* 剧本
     * 剧本, 你可以把它理解为一个Manager, 他可以处理大事, 也可以处理小事, 小到比如一个小任务, 让你去杀5只野猪,
     * 大到他可以是整个游戏流程的剧本, 决定你整个游戏生涯, 触发什么剧情, 世界线发生何种改变
     * 然后, 剧本的特点就是他带有数据存储.
     * 具体用例
     * 1、开启一场出征(像元气骑士那样, 开启一场冒险, 带过程, 带规则, 有结算)
     * 2、领取一个任务
     * 3、游戏故事线(一个存档)
     *
     * 步骤:
     * 比如现在我要开启一场出征, 我需要有一个出征管理器, 这个出征管理器是由管理器和剧本组件组成.
     * 以一个档案(record)为单位, 开启一个剧本, 每个剧本下具体哪些node, 可以随便添加
     *
     * 剧本默认不会每帧都Tick, 只在被通知需要的时候, 才会进行一次Tick. 这是因为剧本树的特点往往都是通过注册事件来驱动推进的, 所以往往不需要update, 默认关闭Tick可以一定程度节约性能
     */
    [Serializable]
    [MemoryPackable(GenerateType.NoGenerate)]
    public abstract partial class Screenplay<TNode> : BehaviorTree<TNode>, IScreenplay where TNode : class, INode {
        [MemoryPackIgnore]
        protected bool dirtyUpdate;

        public void NotifyUpdate() {
            this.dirtyUpdate = true;
        }

        protected override void OnUpdate() {
            if (!this.dirtyUpdate)
                return;

            this.dirtyUpdate = false;
            this.Run();
        }

        protected virtual NodeStatus Run() {
            this.DeltaTime = TimeInfo.DeltaTime;
            var status = this.Tick();
            return status;
        }
    }
}